package com.zxhhyj.storm.database

import androidx.sqlite.SQLITE_DATA_BLOB
import androidx.sqlite.SQLITE_DATA_FLOAT
import androidx.sqlite.SQLITE_DATA_INTEGER
import androidx.sqlite.SQLITE_DATA_NULL
import androidx.sqlite.SQLITE_DATA_TEXT
import androidx.sqlite.execSQL
import com.zxhhyj.storm.database.sqlite.SQLiteConnection
import com.zxhhyj.storm.database.sqlite.SQLiteStatement
import com.zxhhyj.storm.schema.DataType

@Suppress("NOTHING_TO_INLINE")
inline fun Database(sqliteConnection: androidx.sqlite.SQLiteConnection) = Database(GoogleSQLiteConnectionProxy(sqliteConnection))

class GoogleSQLiteConnectionProxy(private val sqliteConnection: androidx.sqlite.SQLiteConnection) : SQLiteConnection {

    override fun inTransaction(): Boolean {
        return sqliteConnection.inTransaction()
    }

    override fun execSQL(sql: String) {
        sqliteConnection.execSQL(sql)
    }

    override fun prepare(sql: String): SQLiteStatement {
        return GoogleSQLiteStatementProxy(sqliteConnection.prepare(sql))
    }

    override fun close() {
        sqliteConnection.close()
    }
}

class GoogleSQLiteStatementProxy(private val sqliteStatement: androidx.sqlite.SQLiteStatement) : SQLiteStatement {

    override fun bindBlob(index: Int, value: ByteArray) {
        sqliteStatement.bindBlob(index, value)
    }

    override fun bindDouble(index: Int, value: Double) {
        sqliteStatement.bindDouble(index, value)
    }

    override fun bindLong(index: Int, value: Long) {
        sqliteStatement.bindLong(index, value)
    }

    override fun bindText(index: Int, value: String) {
        sqliteStatement.bindText(index, value)
    }

    override fun bindNull(index: Int) {
        sqliteStatement.bindNull(index)
    }

    override fun getBlob(index: Int): ByteArray {
        return sqliteStatement.getBlob(index)
    }

    override fun getDouble(index: Int): Double {
        return sqliteStatement.getDouble(index)
    }

    override fun getLong(index: Int): Long {
        return sqliteStatement.getLong(index)
    }

    override fun getText(index: Int): String {
        return sqliteStatement.getText(index)
    }

    override fun isNull(index: Int): Boolean {
        return sqliteStatement.isNull(index)
    }

    override fun getColumnCount(): Int {
        return sqliteStatement.getColumnCount()
    }

    override fun getColumnName(index: Int): String {
        return sqliteStatement.getColumnName(index)
    }

    override fun getColumnType(index: Int): DataType {
        return when (sqliteStatement.getColumnType(index)) {
            SQLITE_DATA_INTEGER -> {
                DataType.INTEGER
            }

            SQLITE_DATA_FLOAT -> {
                DataType.REAL
            }

            SQLITE_DATA_TEXT -> {
                DataType.TEXT
            }

            SQLITE_DATA_BLOB -> {
                DataType.BLOB
            }

            SQLITE_DATA_NULL -> DataType.NULL

            else -> {
                throw RuntimeException("Unknown DataType, index: $index")
            }
        }
    }

    override fun step(): Boolean {
        return sqliteStatement.step()
    }

    override fun reset() {
        sqliteStatement.reset()
    }

    override fun clearBindings() {
        sqliteStatement.clearBindings()
    }

    override fun close() {
        sqliteStatement.close()
    }
}